Shooting victims by block

Which Chicago block has the most shooting victims so far this year?

Fetch the data from NewsroomDB

NewsroomDB is the Tribune's proprietary database for tracking data that needs to be manually entered and validated rather than something that can be ingested from an official source. It's mostly used to track shooting victims and homicides. As far as I know, CPD doesn't provide granular data on shooting victims and the definition of homicide can be tricky (and vary from source to source).

We'll grab shooting victims from the shootings collection.


In [31]:
import os
import requests

def get_table_url(table_name, base_url=os.environ['NEWSROOMDB_URL']):
    return '{}table/json/{}'.format(os.environ['NEWSROOMDB_URL'], table_name)

def get_table_data(table_name):
    url = get_table_url(table_name)
    
    try:
        r = requests.get(url)
        return r.json()
    except:
        print("Request failed. Probably because the response is huge.  We should fix this.")
        return get_table_data(table_name)

shooting_victims = get_table_data('shootings')

print("Loaded {} shooting victims".format(len(data['shooting_victims'])))


Loaded 11713 shooting victims

Filter to only shootings this year


In [32]:
from datetime import date, datetime

def get_shooting_date(shooting_victim):
    return datetime.strptime(shooting_victim['Date'], '%Y-%m-%d')

def shooting_is_this_year(shooting_victim, today):
    try:
        shooting_date = get_shooting_date(shooting_victim)
    except ValueError:
        if shooting_victim['RD Number']:
            msg = "Could not parse date for shooting victim with RD Number {}".format(
                shooting_victim['RD Number'])
        else:
            msg = "Could not parse date for shooting victim with record ID {}".format(
                shooting_victim['_id'])
        
        print(msg)
        return False
        
    return shooting_date.year == today.year

today = date.today()

# Use a list comprehension to filter the shooting victims to ones that
# occured on or before today's month and day.
# Also sort by date because it makes it easier to group by year
shooting_victims_this_year = sorted([sv for sv in shooting_victims
                                       if shooting_is_this_year(sv, today)],
                                      key=get_shooting_date)


Could not parse date for shooting victim with RD Number HX448309
Could not parse date for shooting victim with record ID 560bc169db573e1c2c67789e
Could not parse date for shooting victim with record ID 565d8490389ce82a2a5b07dc
Could not parse date for shooting victim with record ID 56d6c55e389ce82a2a5b09ac
Could not parse date for shooting victim with record ID 536b0f4edb573e257039a258
Could not parse date for shooting victim with record ID 53693edc389ce83e25cd4823
Could not parse date for shooting victim with record ID 536cf216db573e256fa3af22
Could not parse date for shooting victim with record ID 53ac49c8389ce835c90b18b9
Could not parse date for shooting victim with record ID 536cf773389ce835c8d88b28
Could not parse date for shooting victim with record ID 5421c1c1db573e3dc9db2e98
Could not parse date for shooting victim with RD Number HX445856
Could not parse date for shooting victim with RD Number HX447455
Could not parse date for shooting victim with RD Number HY182250
Could not parse date for shooting victim with record ID 552c0a0f389ce8650e9a9916
Could not parse date for shooting victim with record ID 55c79ce6389ce865f1892777
Could not parse date for shooting victim with RD Number HY369178
Could not parse date for shooting victim with record ID 565d882edb573e070ae4c259
Could not parse date for shooting victim with record ID 565da430389ce82a2bd86b3b
Could not parse date for shooting victim with record ID 56e09073389ce82a2a5b09d1

Get the block address


In [37]:
import re

def blockify(address):
    """
    Convert a street address to a block level address
    
    Example:
    
    >>> blockify("1440 W 84th St, Chicago, IL 60620")
    '1400 W 84th St, Chicago, IL 60620'
    
    """
    m = re.search(r'^(?P<address_number>\d+) ', address)
    address_number = m.group('address_number')
    block_address_number = (int(address_number) // 100) * 100
    return address.replace(address_number, str(block_address_number))
    

def add_block(sv):
    """Make a copy of a shooting victim record with an added block field"""
    with_block = dict(**sv)
    
    if not sv['Shooting Location']:
        # No location, just set block to none
        print("Record with RD number {0} has no location.".format(
            sv['RD Number']))
        with_block['block'] = None
        return with_block
            
    if sv['Shooting Specificity'] == 'Exact':
        # Address is exact, convert to 100-block
        with_block['block'] = blockify(sv['Shooting Location'])
    else:
        # Address is already block. Use it
        with_block['block'] = sv['Shooting Location']
        
    return with_block

# Create a list of shooting victim dictionaries with blocks
shooting_victims_this_year_with_block = [add_block(sv) for sv in shooting_victims_this_year]


Record with RD number  has no location.
Record with RD number  has no location.

Count victims by block


In [45]:
import pandas as pd

# Load shooting victims into a dataframe,
# filtering out victim records for which we couldn't determine the block
shooting_victims_this_year_df = pd.DataFrame([sv for sv in shooting_victims_this_year_with_block if sv['block'] is not None])

# Group by block
shooting_victims_this_year_by_block = shooting_victims_this_year_df.groupby('block').size().sort_values(ascending=False)
shooting_victims_this_year_by_block


Out[45]:
block
4400 W Monroe St, Chicago, IL 60624                  6
7000 S Paxton Ave, Chicago, IL 60649                 5
1500 S Kedzie Ave, Chicago, IL 60623                 5
6800 S Throop St, Chicago, IL 60636                  4
6500 S Green St, Chicago, IL 60621                   4
3700 W Polk St, Chicago, IL 60624                    4
4300 W Wilcox St, Chicago, IL 60624                  4
5700 W Washington Blvd, Chicago, IL 60644            4
E 48th St & King Dr, Chicago, IL 60615               4
5500 W Congress Pkwy, Chicago, IL 60644              4
4600 W West End Ave, Chicago, IL 60644               4
3700 W Division St, Chicago, IL 60651                3
3700 W Grenshaw St, Chicago, IL 60624                3
3800 South Princeton, Chicago, IL                    3
3900 W Thomas St, Chicago, IL 60651                  3
4000 W 18th St, Chicago, IL 60623                    3
4100 W 25th St, Chicago, IL 60623                    3
4100 W Adams St, Chicago, IL 60624                   3
W Chicago Ave & N St Louis Ave, Chicago, IL 60651    3
500 S Lavergne Ave, Chicago, IL 60644                3
500 S Kostner Ave, Chicago, IL 60624                 3
1900 W Belle Plaine Ave, Chicago, IL 60613           3
5718 S Green St, Chicago, IL 60621                   3
800 N St Louis Ave, Chicago, IL 60651                3
600 N Lake Shore Dr, Chicago, IL 60611               3
800 N Central Park Ave, Chicago, IL 60651            3
6400 S Eggleston Ave, Chicago, IL 60621              3
6800 S Lawndale Ave, Chicago, IL 60629               3
7500 S State St, Chicago, IL 60619                   3
200 N Pulaski Rd, Chicago, IL 60624                  3
                                                    ..
4800 S Bishop St, Chicago, IL 60609                  1
4800 N. Lake Shore Drive                             1
8300 S Stewart Ave, Chicago, IL 60620                1
4700 W Jackson Blvd, Chicago, IL 60644               1
4700 W Huron St, Chicago, IL 60644                   1
8300 S Winchester Ave, Chicago, IL 60620             1
4700 S Vincennes Ave, Chicago, IL 60615              1
4700 S Laflin St, Chicago, IL 60609                  1
4700 S Hamlin Ave, Chicago, IL 60632                 1
4700 S Federal St, Chicago, IL 60609                 1
8300 S Lafayette Ave, Chicago, IL 60620              1
4900 N Harding Ave, Chicago, IL 60625                1
500 W Kinzie St, Chicago, IL 60654                   1
4900 S Laflin St, Chicago, IL 60609                  1
8300 S Cottage Grove Ave, Chicago, IL 60619          1
8300 S Houston Ave, Chicago, IL 60617                1
500 S Cicero Ave, Chicago, IL 60644                  1
500 S California Ave, Chicago, IL 60612              1
500 N Mayfield Ave, Chicago, IL 60644                1
500 N Lawler Ave, Chicago, IL 60644                  1
500 E Grand Ave, Chicago, IL 60611                   1
500 E 33rd St, Chicago, IL 60616                     1
500 E 115th St, Chicago, IL 60628                    1
8300 S Justine St, Chicago, IL 60620                 1
50 S Leamington Ave, Chicago, IL 60644               1
4900 W Madison St, Chicago, IL 60644                 1
4900 W Division St, Chicago, IL 60651                1
4900 W Augusta Blvd, Chicago, IL 60651               1
4900 W Adams St, Chicago, IL 60644                   1
4600 N Central Park Ave, Chicago, IL 60625           1
dtype: int64

In [48]:
# Output to a CSV file so I can email to the reporter who requested it
shooting_victims_this_year_by_block.to_csv("shooting_victims_by_block.csv")

In [ ]: